home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / elvis-17.lha / elvis-1.7 / elvrec.c < prev    next >
C/C++ Source or Header  |  1993-01-06  |  4KB  |  203 lines

  1. /* elvrec.c */
  2.  
  3. /* This file contains the file recovery program */
  4.  
  5. /* Author:
  6.  *    Steve Kirkendall
  7.  *    14407 SW Teal Blvd. #C
  8.  *    Beaverton, OR 97005
  9.  *    kirkenda@cs.pdx.edu
  10.  */
  11.  
  12.  
  13. #include <stdio.h>
  14. #include "config.h"
  15. #include "vi.h"
  16.  
  17. void recover P_((char *, char *));
  18. void main P_((int, char **));
  19.  
  20.  
  21. void recover(basename, outname)
  22.     char    *basename;    /* the name of the file to recover */
  23.     char    *outname;    /* the name of the file to write to */
  24. {
  25.     char    pathname[500];    /* full pathname of the file to recover */
  26.     char    line[600];    /* a line from the /usr/preserve/Index file */
  27.     int    ch;        /* a character from the text being recovered */
  28.     FILE    *from;        /* the /usr/preserve file, or /usr/preserve/Index */
  29.     FILE    *to;        /* the user's text file */
  30.     char    *ptr;
  31. #if OSK
  32.     int        uid;
  33. #endif
  34.  
  35.     /* convert basename to a full pathname */
  36.     if (basename)
  37.     {
  38. #ifndef CRUNCH
  39. # if MSDOS || TOS
  40.         if (!basename[0] || basename[1] != ':')
  41. # else
  42.         if (basename[0] != SLASH)
  43. # endif
  44.         {
  45.             ptr = getcwd(pathname, sizeof pathname);
  46.             if (ptr != pathname)
  47.             {
  48.                 strcpy(pathname, ptr);
  49.             }
  50.             ptr = pathname + strlen(pathname);
  51.             *ptr++ = SLASH;
  52.             strcpy(ptr, basename);
  53.         }
  54.         else
  55. #endif
  56.         {
  57.             strcpy(pathname, basename);
  58.         }
  59.     }
  60.  
  61. #if OSK
  62.     uid = getuid();
  63.     if(setuid(0))
  64.         exit(_errmsg(errno, "Can't set uid\n"));
  65. #endif
  66.     /* scan the /usr/preserve/Index file, for the *oldest* unrecovered
  67.      * version of this file.
  68.      */
  69.     from = fopen(PRSVINDEX, "r");
  70.     while (from && fgets(line, sizeof line, from))
  71.     {
  72.         /* strip off the newline from the end of the string */
  73.         line[strlen(line) - 1] = '\0';
  74.  
  75.         /* parse the line into a "preserve" name and a "text" name */
  76.         for (ptr = line; *ptr != ' '; ptr++)
  77.         {
  78.         }
  79.         *ptr++ = '\0';
  80.  
  81.         /* If the "preserve" file is missing, then ignore this line
  82.          * because it describes a file that has already been recovered.
  83.          */
  84.         if (access(line, 0) < 0)
  85.         {
  86.             continue;
  87.         }
  88.  
  89.         /* are we looking for a specific file? */
  90.         if (basename)
  91.         {
  92.             /* quit if we found it */
  93.             if (!strcmp(ptr, pathname))
  94.             {
  95.                 break;
  96.             }
  97.         }
  98.         else
  99.         {
  100.             /* list this file as "available for recovery" */
  101.             puts(ptr);
  102.         }
  103.     }
  104.  
  105.     /* file not found? */
  106.     if (!basename || !from || feof(from))
  107.     {
  108.         if (from != NULL) fclose(from);
  109.         if (basename)
  110.         {
  111.             fprintf(stderr, "%s: no recovered file has that exact name\n", pathname);
  112.         }
  113.         return;
  114.     }
  115.     if (from != NULL) fclose(from);
  116.  
  117.     /* copy the recovered text back into the user's file... */
  118.  
  119.     /* open the /usr/preserve file for reading */
  120.     from = fopen(line, "r");
  121.     if (!from)
  122.     {
  123.         perror(line);
  124.         exit(2);
  125.     }
  126.  
  127. #if ANY_UNIX
  128.     /* Be careful about user-id.  We want to be running under the user's
  129.      * real id when we open/create the user's text file... but we want
  130.      * to be superuser when we delete the /usr/preserve file.  For UNIX,
  131.      * we accomplish this by deleting the /usr/preserve file *now*,
  132.      * when it is open but before we've read it.  Then we revert to the
  133.      * user's real id.
  134.      */
  135.     unlink(line);
  136.     setuid(getuid());
  137. #endif
  138. #if OSK
  139.     setuid(uid);
  140. #endif
  141.  
  142.     if (outname == NULL) return;
  143.  
  144.     /* open the user's file for writing */
  145.     to = fopen(outname, "w");
  146.     if (!to)
  147.     {
  148.         perror(ptr);
  149.         exit(2);
  150.     }
  151.  
  152.     /* copy the text */
  153.     while ((ch = getc(from)) != EOF)
  154.     {
  155.         putc(ch, to);
  156.     }
  157.  
  158. #if !ANY_UNIX
  159. #if OSK
  160.     fclose(from);
  161.     setuid(0);
  162. #endif
  163.     /* delete the /usr/preserve file */
  164.     unlink(line);
  165. #if OSK
  166.     setuid(uid);
  167. #endif
  168. #endif
  169. }
  170.  
  171. void
  172. main(argc, argv)
  173.     int    argc;
  174.     char    **argv;
  175. {
  176.     /* check arguments */
  177.     if (argc > 3)
  178.     {
  179.         fprintf(stderr, "usage: %s [preserved_file [recovery_file]]\n", argv[0]);
  180.         exit(2);
  181.     }
  182.  
  183.     /* recover the requested file, or list recoverable files */
  184.     if (argc == 3)
  185.     {
  186.         /* recover the file, but write it to a different filename */
  187.         recover (argv[1], argv[2]);
  188.     }
  189.     else if (argc == 2)
  190.     {
  191.         /* recover the file */
  192.         recover(argv[1], argv[1]);
  193.     }
  194.     else
  195.     {
  196.         /* list the recoverable files */
  197.         recover((char *)0, (char *)0);
  198.     }
  199.  
  200.     /* success! */
  201.     exit(0);
  202. }
  203.